package com.xjc.infra.encrypt;

import java.security.Key;
import java.security.cert.X509Certificate;

import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.xjc.infra.encrypt.entity.KeyInfo;
import com.xjc.infra.encrypt.entity.STSPackage;
import com.xjc.infra.exception.IFSException;
import com.xjc.infra.util.SystemGlobals;

/**
 * 加密/解密
 * @author liangcz
 * @Date   2018年1月2日 下午7:54:49
 * @version 1.0
 */
@Component
public class EncryptUtil {
	@Autowired
	KeyFactory keyFactory;
	/**
	 * 加密
	 * @author liangcz
	 * @date   2018年1月2日 下午7:56:10
	 * @return String
	 */
	public String encrypt(Object obj){
		try {
			String encoding = SystemGlobals.getProperty("sys.encoding","UTF-8");
			/* 1、加密 */
			String plainMsg = JSON.toJSONString(obj);
			Key key = SecurityUtil.generateSymmetricKey();
			byte[] encryptedTextBuf = SecurityUtil.encryptSymmetry(plainMsg, key);
			X509Certificate cert = keyFactory.getCert();
			byte[] encryptedKeyBuf = SecurityUtil.encryptSymmetricKey(key,cert.getPublicKey());
			/* 2、包装 */
			STSPackage sp = new STSPackage();
			sp.setEncryptedText(Base64.encodeBase64String(encryptedTextBuf));
			KeyInfo keyInfo = new KeyInfo();
			keyInfo.setEncryptedKey(Base64.encodeBase64String(encryptedKeyBuf));
			keyInfo.setReceiverX509CertSN(cert.getSerialNumber().toString(10));
			sp.setKeyInfo(keyInfo);
			String message = JSON.toJSONString(sp);
			String encryptMsg = Base64.encodeBase64String(message.getBytes(encoding));
			return encryptMsg;
		} catch (IFSException e) {
			throw e;
		} catch (Exception e) {
			throw new IFSException(e, "EncryptUtil.encrypt.99","加密失败");
		}
	}
	/**
	 * 解密
	 * @author liangcz
	 * @date   2018年1月2日 下午8:07:59
	 * @return T
	 */
	public <T> T decrypt(String encryptMsg,Class<T> responseType){
		try {
			String encoding = SystemGlobals.getProperty("sys.encoding","UTF-8");
			String sTSPackageText = new String(Base64.decodeBase64(encryptMsg),encoding);
			/* 1、拆包装 */
			STSPackage sTSPackage = JSON.parseObject(sTSPackageText, STSPackage.class);
			String encryptedKey = sTSPackage.getKeyInfo().getEncryptedKey();
			/* 2、 解密 */
			String encryptedText = sTSPackage.getEncryptedText(); // 加密报文实体
			Key key = SecurityUtil.decryptSymmetricKey(Base64.decodeBase64(encryptedKey), keyFactory.getPrivateKey());	
			String plainText = SecurityUtil.decryptSymmetry(Base64.decodeBase64(encryptedText), key);
			T t = null;
			if(responseType.isAssignableFrom(String.class)){
				t = (T) plainText;
			}else{
				t = JSON.parseObject(plainText, responseType);
			}
			return t;
		} catch (IFSException e) {
			throw e;
		} catch (Exception e) {
			throw new IFSException(e, "EncryptUtil.decrypt.99","解密失败");
		}
	}
}
